#ifndef COMMONFUNC_H
#define COMMONFUNC_H

#include <QObject>
#include <QAction>
#include <QString>
#include <QtDebug>
#include <QVBoxLayout>
#include <QTextEdit>
#include <QTextBrowser>
#include <QApplication>
#include <QClipboard>
#include <QLabel>
#include <QFrame>
#include <QDateTime>
#include <QFile>
#include <QFileDialog>
#include <QMutex>
#include <QtGlobal>
#include <QPushButton>
#include <QMessageBox>

#include <string>
#include <mutex>

#include "CustomComponents.h"

#define GLOBAL_RUNNING_LOGNAME  "run.log"
#define FILE_HELPINFO           "readme.jpg"  // 帮助信息文本

typedef enum _SHOWTIME_TYPE_
{
    SHOWTIME_TYPE_STAMP                 = 0,    // 以时间戳形式展示
    SHOWTIME_TYPE_YYYYMMDDhhmmss        = 1,    // 以yyyy-mm-dd hh:mm:ss形式展示
    SHOWTIME_TYPE_hhmmss                = 2     // 以hh:mm:ss形式展示
}SHOWTIME_TYPE;

typedef enum _MSG_TYPE_
{
    MSG_TYPE_INFO         = 0,
    MSG_TYPE_ERROR        = 1,
    MSG_TYPE_WARN         = 2
}MSG_TYPE;

typedef enum _IMG_TYPE_
{
    IMG_TYPE_UNKNOW      = 0,
    IMG_TYPE_JPG         = 1,
    IMG_TYPE_JPEG        = 2,
    IMG_TYPE_PNG         = 3,
    IMG_TYPE_GIF         = 4
}IMG_TYPE;

typedef struct _IMG_RECT_INT_
{
    uint iX;
    uint iY;
    uint iWidth;
    uint iHeight;
}IMG_RECT_INT;

typedef struct _IMG_RECT_FLOAT_
{
    float fX;
    float fY;
    float fWidth;
    float fHeight;

    // 校验坐标值是否在[0, 1.0]之间
    bool check()
    {
        return !(fX < 0 || fY < 0 || fWidth < 0 || fHeight < 0 || fX > 1 || fY > 1 || fWidth > 1 || fHeight > 1);
    }
}IMG_RECT_FLOAT;

// 通用接口
QAction* NewAction(const QString strName, const QString strStatusTip, const char *amember);

// 新建带图标按钮
QPushButton *NewPTBWithIcon(const QString strTitle, const QString strTip, const QIcon &icon, QWidget *parent = nullptr);

// 设置按钮风格
MyPushButton* newFuncWithIndex(QString strTitle, uint iKey, const QString strTip, const QIcon &icon);

// 按格式要求返回当前时间戳
QString GetCurrentTime(const SHOWTIME_TYPE eTimeType);

// 计算数字位数
int CountNumber(unsigned int iNum);

// 打开文件窗口，并选取指定文件
QString GetFileFromFileDialog(QWidget *parent, const QString &strFileParam);

// 将数据写入到文件中
bool WriteContext2File(const QString &strFileName, const QString &strContext);

// 日志记录MessageHandler
void outputMessage(QtMsgType type, const QMessageLogContext &context, const QString &msg);

// 判断文件是否存在
bool FileExist(const QString &strFileName);

// [C++] 以二进制方式从文件中读取数据
bool ReadFileByBinary(const std::string &strFile, std::string &strContext);

// [C++] 以二进制方式向文件中写入数据
bool WriteBinary2File(const std::string &strFile, std::string &strContext);

// 验证文本是否为JSON
bool isValidJSON(std::string strJson);

// 将json报文转换为无格式化报文
bool getUnformattedcJSON(std::string &strJson);

// 往TextBrowser打印指定颜色内容，用于日志窗口
void appendLogMsg(QTextBrowser *pQTextBrowser, const MSG_TYPE iType, const QString &str);

// 从图片二进制数据中提取图片类型
IMG_TYPE getImgTypeFromBinary(const std::string strImg);

// 将十进制数字转换为指定位数的十六进制数字
QString getNum2HexString(int iNum, int prec);

// 判断所在系统是否为大端存储
bool IsBigEndian();

// 获取本机IP地址
QString getMyIpString();

// 校验输入IP是否为IPv4
bool checkIPv4(const QString &strSrc);

// 校验有效数字
bool checkValidNumber(QString &strSrc);

// 中文路径支持
QString getPath2Chinese(const QString &strPath);

// JSON文本转义
bool getJSON2Translation(const std::string &strContext, std::string &strResult);

// 转义JSON文本去转义
bool getTranslation2JSON(const std::string &strContext, std::string &strResult);

// 根据相对坐标值在图片上画框
//bool picDrawRect(QImage &pImg, const IMG_RECT_FLOAT &stRect, const QRgb pColour, const uint pSize);

// 根据限定范围进行校验
void checkNumWithRange(uint &iNum, const uint iMin, const uint iMax);

// 根据归一化坐标值在图片上画框
bool picDrawRectNormalization(QImage &pImg, const IMG_RECT_FLOAT &stRect, const QRgb pColour, const uint pSize);

// 根据真实坐标值在图片上画框
bool picDrawRectLocation(QImage &pImg, const IMG_RECT_INT &stRect, const QRgb pColour, const uint pSize);

// 根据相对坐标在图片上画点
bool picDrawPoint(QImage &pImg, const IMG_RECT_FLOAT &stRect, const QRgb pColour, const uint pSize);

// 根据路径获取图片数据
bool getImgFromPath(QImage &pImg, const QString& strPath);

// 根据路径提取文件格式，以.为依据
QString getFormatFromFile(const QString& strPath);


#endif // COMMONFUNC_H
